package options

import (
	"fmt"

	"github.com/mars/pkg/loggers"
	"github.com/spf13/pflag"
)

// LogOption 参考 pkg/loggers/config.go
type LogOptions struct {
	FileName   string   `mapstructure:"file-name"   json:"file-name"`
	MaxSize    int      `mapstructure:"max-size"    json:"max-size"`
	MaxBackups int      `mapstructure:"max-backups" json:"max-backups"`
	MaxAge     int      `mapstructure:"max-age"     json:"max-age"`
	Compress   bool     `mapstructure:"compress"    json:"compress"`
	Level      string   `mapstructure:"level"       json:"level"`
	FieldKeys  []string `mapstructure:"field-keys"  json:"field-keys"`
}

func NewLogOptions() *LogOptions {
	return &LogOptions{
		FileName:   "stderr",
		MaxSize:    10,
		MaxBackups: 20,
		MaxAge:     30,
		Compress:   true,
		Level:      "INFO",
	}
}

func (o *LogOptions) AddFlags(fs *pflag.FlagSet) {
	fs.StringVar(&o.FileName, "log.file-name", o.FileName, "Specify the log file path, stdout、stderr、discard or os filepath is optional.")
	fs.IntVar(&o.MaxSize, "log.max-size", o.MaxSize, "Specify the single log file max size, the unit is MBit.")
	fs.IntVar(&o.MaxBackups, "log.max-backups", o.MaxBackups, "Specify the log file maximum number of backups.")
	fs.IntVar(&o.MaxAge, "log.max-age", o.MaxAge, "Specify the log file maximum days to maintain.")
	fs.BoolVar(&o.Compress, "log.compress", o.Compress, "Specify the rules of log compress.")
	fs.StringVar(&o.Level, "log.level", o.Level, "Specify the log level, DEBUG, INFO, WARN, ERROR is optional.")
	fs.StringSliceVar(&o.FieldKeys, "log.field-keys", o.FieldKeys, "Specify the keys acquired from context.Context.")
}

func (o *LogOptions) Validate() []error {
	var errs = []error{}
	if o.MaxSize < 0 || o.MaxBackups < 0 || o.MaxAge < 0 {
		errs = append(errs,
			fmt.Errorf("--log.max-size %v, --log.max-backups %v, --log.max-age %v is not allow to less than 0",
				o.MaxSize, o.MaxBackups, o.MaxAge))
	}

	if o.Level != "DEBUG" && o.Level != "INFO" && o.Level != "WARN" && o.Level != "ERROR" {
		errs = append(errs, fmt.Errorf("--log.level could only be the one of  DEBUG, INFO, WARN, ERROR, but receive: %s", o.Level))
	}

	return errs
}

func (o *LogOptions) NewLogConfig() *loggers.Config {
	return &loggers.Config{
		FileName:   o.FileName,
		MaxSize:    o.MaxSize,
		MaxBackups: o.MaxBackups,
		MaxAge:     o.MaxAge,
		Compress:   o.Compress,
		Level:      o.Level,
		FieldKeys:  o.FieldKeys,
	}
}
